﻿using HeyRed.Mime;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Tmp.Models;

namespace Tmp.Controllers;

[Route("download")]
public class DownloadController : Controller
{
    private readonly Configuration Configuration;

    public DownloadController(IOptions<Configuration> options)
    {
        Configuration = options.Value;
    }

    [HttpHead("file/{cipher}/{filePath}")]
    public IActionResult HttpHead(string filePath, string cipher)
    {
        // 构建文件的完整路径
        var fullPath = Path.Combine(Configuration.UploadPath, $"{cipher}", filePath);

        // 检查文件是否存在
        if (!System.IO.File.Exists(fullPath))
        {
            return NotFound();
        }
        Response.Headers.Add("Accept-Ranges", "bytes");
        return Ok();
    }



    [HttpGet("file/{cipher}/{filePath}")]
    public IActionResult Download(string filePath, string cipher)
    {
        // 构建文件的完整路径
        var fullPath = Path.Combine(Configuration.UploadPath, $"{cipher}", filePath);

        // 检查文件是否存在
        if (!System.IO.File.Exists(fullPath))
        {
            return NotFound();
        }

        // 获取文件信息
        var fileInfo = new FileInfo(fullPath);
        var fileSize = fileInfo.Length;

        // 检查是否支持断点续传
        var isRangeRequest = Request.Headers.ContainsKey("Range");
        if (isRangeRequest)
        {
            // 解析 Range 头部，获取断点续传的起始位置和结束位置
            var rangeHeader = Request.Headers["Range"].ToString();
            var (startByte, endByte) = GetRange(rangeHeader, fileSize);

            // 设置响应头部
            Response.StatusCode = 206; // Partial Content
            Response.Headers.Add("Accept-Ranges", "bytes");
            Response.Headers.Add("Content-Range", $"bytes {startByte}-{endByte}/{fileSize}");
            Response.Headers.Add("Content-Type", MimeTypesMap.GetMimeType(fullPath));
            Response.Headers.Add("Content-Disposition", $"attachment; filename=\"{Path.GetFileName(filePath)}\"");

            // 设置响应内容
            var fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            fileStream.Seek(startByte, SeekOrigin.Begin);
            using var fileStream0 = new FileStream(fullPath, FileMode.Open, FileAccess.Read);
            // 设置文件流的位置为起始字节位置
            fileStream0.Position = startByte;

            // 计算要读取的字节数
            var totalBytesToRead = endByte - startByte + 1;

            // 创建一个字节数组来存储读取的字节
            var buffer = new byte[totalBytesToRead];

            // 从文件流中读取字节
            var bytesRead = fileStream.Read(buffer, 0, (int)totalBytesToRead);

            // 创建 FileStreamResult 对象并设置相关属性
            var result = new FileStreamResult(new MemoryStream(buffer), "application/octet-stream");
            return result;
        }

        // 设置响应头部
        Response.Headers.Add("Accept-Ranges", "bytes");
        Response.Headers.Add("Content-Disposition", $"attachment; filename=\"{Path.GetFileName(filePath)}\"");
        Response.Headers.Add("Content-Type", MimeTypesMap.GetMimeType(fullPath));
        Response.Headers.Add("Content-Range", $"bytes {0}-{fileSize-1}/{fileSize}");
        // 设置响应内容
        var fileBytes = System.IO.File.ReadAllBytes(fullPath);
        return File(fileBytes, "application/octet-stream");
    }

    private (long startByte, long endByte) GetRange(string rangeHeader, long fileSize)
    {
        if (rangeHeader.Length <= 6) return (0, fileSize);
        var ranges = rangeHeader[6..].Split("-");
        try
        {
            if (ranges[1].Length > 0)
            {
                return (long.Parse(ranges[0]), long.Parse(ranges[1]));
            }
        }
        catch (Exception)
        {
            return (long.Parse(ranges[0]), fileSize-1);
        }

        return (long.Parse(ranges[0]), fileSize-1);
    }

}